/**
 * *************************************
 * Copyright(c)2016 Dingdang Yixia 
 * All Rights Reserved.
 *
 * @File: EventDataHandleServiceImpl.java
 * @Package: com.ddyx.service.impl
 * @Description:
 * 
 * @Version: V1.0
 * @Author: Yidong.Xiang
 * @Date: 2018年1月11日 下午7:06:17
 * 
 * *************************************
 */
package com.ddyx.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.ddyx.common.SimpleHttpPost;
import com.ddyx.entity.Customer;
import com.ddyx.entity.EventLog;
import com.ddyx.entity.EventStorelog;
import com.ddyx.entity.FaceNotice;
import com.ddyx.entity.ReportArrivalCount;
import com.ddyx.entity.Shop;
import com.ddyx.entity.StoreEvent;
import com.ddyx.mapper.CustomerMapper;
import com.ddyx.mapper.EventLogMapper;
import com.ddyx.mapper.EventStorelogMapper;
import com.ddyx.mapper.FaceNoticeMapper;
import com.ddyx.mapper.ReportArrivalCountMapper;
import com.ddyx.mapper.ShopMapper;
import com.ddyx.mapper.StoreEventMapper;
import com.ddyx.service.EventDataHandleService;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName: EventDataHandleServiceImpl.java
 * @Module: 事件数据处理模块
 * @Description: 
 * 
 * @author: Yidong.Xiang
 * @date: 2018年1月11日 下午7:06:17
 * 
 */
@Slf4j
@Service
public class EventDataHandleServiceImpl implements EventDataHandleService {
	
	//发送通知的接口
	static String url = "http://ppe.retail.vip/vip-pushservice/push/pushNotice";
	@Resource
	StoreEventMapper storeEventMapper;
	@Resource
	CustomerMapper customerMapper;
	@Resource
	EventLogMapper eventLogMapper;
	@Resource
	EventStorelogMapper eventStorelogMapper;
	@Resource
	FaceNoticeMapper faceNoticeMapper;
	@Resource
	ShopMapper shopMapper;
	@Resource 
	ReportArrivalCountMapper reportArrivalCountMapper;
	//报表
	
	@Override
	public JSONObject handle(JSONObject eventData) {
		int r = 0;
		JSONObject success = new JSONObject();
		success.put("status", "success");
		JSONObject failed = new JSONObject();
		failed.put("status", "failed");
		try {
			//保存原始的事件数据
			StoreEvent event = saveEventData(eventData);
			if(event==null) return failed;
			
			int shopId = event.getShopId();
			Shop queryParm = new Shop();
			queryParm.setShopId(shopId);
			Shop shop = shopMapper.selectOne(queryParm);//可以使用单例模式

			//创建一个普通顾客
			r = createCustomer(event,shop);
			//判断vip，是VIP则发提醒通知（同时写通知表），记录vip时间轴事件
			if("true".equals(event.getSearchResult()))
			{
				Customer vip = isVipCustomer(event,shop);
				if(vip!=null) {
					//发送vip进店通知
					pushNotice(event,shop,vip);
					//更新vip顾客的到店次数和进店时间
					updateVipCustomer(vip.getCustomerId(),event.getEventsCount(),event.getCaptureAt());
					//记录提醒记录可统计vip弹出率（支持老接口）
					saveNotice(event,shop);
				}
			}
			r = addStoreEventLog(event,shop);//记录顾客进店记录
			
			//写客流统计人次记录
			
			if(r==1)
				return success;
			return failed;
		}catch(Exception e)
		{
			e.printStackTrace();
			failed.put("status", "error");
			return failed;
		}
		
	}

	/**
	 * 是VIP则发提醒通知（同时写通知表）
	 * @param storeEvent
	 * @return
	 */
	public int saveNotice(StoreEvent storeEvent,Shop shop)
	{
		int r = 0;
		try {
			FaceNotice faceNotice = new FaceNotice();
			faceNotice.setContactId(storeEvent.getContactId());
			faceNotice.setImageUuid(storeEvent.getDetectFace());
			Date noticeDatetime = new Date();
			faceNotice.setMsec(noticeDatetime.getTime());
			faceNotice.setNoticeDatetime(noticeDatetime);
			faceNotice.setNoticeTitle(shop.getStoreName());
			faceNotice.setStoreId(shop.getStoreId());
			r = faceNoticeMapper.insert(faceNotice);
			
		}
		catch(Exception e)
		{
			e.printStackTrace();
			log.error("");
			return 0;
		}
		return r;
	}
	/**
	 * 发送VIP进店提醒消息，
	 * @param storeEvent
	 * @param shop
	 * @return
	 */
	public int pushNotice(StoreEvent storeEvent,Shop shop,Customer vip)
	{
		int r = 0;
		try {
//			String contactId = storeEvent.getContactId();
//			String storeNo = shop.getStoreNo();
//			Customer filter = new Customer();
//			filter.setContactId(contactId);
//			filter.setStoreNo(storeNo);
//			filter.setIsvip(1);
//			//暂时先从mysql中取出customer对象，可改进成从redis获取
//			List<Customer> list = customerMapper.select(filter);
			if(vip!=null)
			{
				JSONObject notice = new JSONObject();
				HashMap<String ,Object> map = new HashMap<String,Object>();
				map.put("storeNo", vip.getStoreNo());
				map.put("customerId", vip.getCustomerId());
				map.put("customerName", vip.getCustomerName());
				map.put("nickname", vip.getNickname());
				map.put("headImage", storeEvent.getDetectFace());
				map.put("gender", vip.getGender());
				map.put("contactId", vip.getContactId());

				map.put("snapTime", vip.getSnapTime());
				map.put("lastDateArrived", vip.getLastDateArrived());
				map.put("totalTimes", vip.getTotalTimes());
				map.put("totalAmount", vip.getTotalAmount());
				map.put("colorName", vip.getColorName());
				map.put("sizeName", vip.getSizeName());
				map.put("styleName", vip.getStyleName());
				map.put("tags", vip.getTags());
				
				notice.put("data", map);
				SimpleHttpPost.getInstance().postJson(url, notice);
				r =1;
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			log.error("");
			return 0;
		}
		return r;
	}
	/**
	 * 根据事件数据获取VIP顾客信息
	 * @param storeEvent
	 * @param shop
	 * @return
	 */
	public Customer isVipCustomer(StoreEvent storeEvent,Shop shop)
	{
		try {
			String contactId = storeEvent.getContactId();
			String storeNo = shop.getStoreNo();
			Customer filter = new Customer();
			filter.setContactId(contactId);
			filter.setStoreNo(storeNo);
			filter.setIsvip(1);
			//暂时先从mysql中取出customer对象，可改进成从redis获取
			List<Customer> list = customerMapper.select(filter);
			if(list!=null)
			{
				if(list.size()>0) {
					Customer customer = list.get(0);
					return customer;
				}
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			log.error("");
			return null;
		}
		return null;		
	}
	/**
	 * 创建一个普通顾客,根据contactId判断是否已存在，若果是则更新VIP到店次数和最近到店时间
	 * @param storeEvent
	 * @return
	 */
	public int createCustomer(StoreEvent storeEvent,Shop shop)
	{
		int r = 0;
		try {
			String patten = "yyyy-MM-dd HH:mm:ss";
			Customer customer = new Customer();
			String snapTime = new SimpleDateFormat(patten).format(storeEvent.getCaptureAt());
			String lastDateArrived = snapTime;
			if(null != storeEvent.getLastCaptureAt())
				lastDateArrived = new SimpleDateFormat(patten).format(storeEvent.getLastCaptureAt());
			String headImage = storeEvent.getDetectFace();
			String contactId = storeEvent.getContactId();
			String gender = "1".equals(storeEvent.getDetectGender())?"男":"女";
			Integer totalTimes = storeEvent.getEventsCount();
			
			customer.setStoreNo(shop.getStoreNo());
			customer.setStoreId(shop.getStoreId());
			
			customer.setContactId(contactId);
			customer.setHeadImage(headImage);
			customer.setSnapTime(snapTime);
			customer.setCustomerUuid(contactId);
			customer.setIsvip(0);
			customer.setTotalTimes(totalTimes);
			customer.setLastDateArrived(lastDateArrived);
			customer.setGender(gender);
			customer.setAge(storeEvent.getDetectAge());
			customer.setAgeGroup(getAgeGroup(storeEvent.getDetectAge()));
			customer.setFacequality(1);

			r = customerMapper.insert(customer);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return 0;
		}
		return r;
	}	
	/**
	 * 更新到店次数和最近到店时间
	 * @param storeEvent
	 * @return
	 */
	public int updateVipCustomer(Integer customerId,Integer totalTimes,Date captureAt)
	{
		int r = 0;
		try {
			String patten = "yyyy-MM-dd HH:mm:ss";
			String lastDateArrived = new SimpleDateFormat(patten).format(captureAt);
			//更新VIP到店次数和最近到店时间
			Customer customer = new Customer();
			customer.setCustomerId(customerId);
			customer.setLastDateArrived(lastDateArrived);
			customer.setTotalTimes(totalTimes);
//			vip.setHeadImage(headImage);
			r = customerMapper.updateLastArrivedInfo(customer);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return 0;
		}
		return r;
	}
	/**
	 * 记录vip时间轴事件
	 * @param storeEvent
	 * @return
	 */
	public int addStoreEventLog(StoreEvent storeEvent,Shop shop)
	{
		int r = 0;
		try {
			String patten = "yyyy-MM-dd HH:mm:ss";
			String contactId = storeEvent.getContactId();
			String headImage = storeEvent.getDetectFace();
			String snapTime = new SimpleDateFormat(patten).format(storeEvent.getCaptureAt());
			//写事件表
			EventLog eventLog = new EventLog();
			eventLog.setContactId(contactId);
			eventLog.setEventType("1");//1:进店,2:购买
			eventLog.setEventTimestamp(snapTime);
			r= eventLogMapper.insert(eventLog);
			
			if(null!=eventLog.getEventId()) {
				EventStorelog storeLog = new EventStorelog();
				storeLog.setContactId(contactId);
				storeLog.setEventId(eventLog.getEventId());
				storeLog.setHeadImage(headImage);
				storeLog.setSnapTime(snapTime);
				storeLog.setStoreName(shop.getStoreName());
				r = eventStorelogMapper.insert(storeLog);
			}
			
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return 0;
		}
		return r;
	}
	/**
	 * 客流统计
	 * @return
	 */
	public int countCustomer(StoreEvent storeEvent)
	{
		int r = 0;
		try {
			ReportArrivalCount count =  new ReportArrivalCount();
			count.setContactId(storeEvent.getContactId());
//			count.setCountDate(countDate);
//			count.setCountHour(countHour);
			count.setSnapCount(1);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return 0;
		}
		return r;
	}	
	
	/**
	 * 将JSONObject类型的事件数据转为PO实体类，并且持久化至mysql表
	 * @param eventData JSONObject类型的事件数据
	 * @return
	 */
	public StoreEvent saveEventData(JSONObject jo) {
		StoreEvent storeEvent = new StoreEvent();
		try {
//			boolean error = jo.containsKey("error");
//			if(error) return null;//此处最好要保存错误日志
			JSONObject event = jo.getJSONObject("event");
			
			JSONObject customer = event.getJSONObject("customer");
			
			Integer eventId = event.getInteger("id");
			Integer shopId = event.getInteger("shop_id");
			Integer deviceId = event.getInteger("device_id");
			String deviceName = event.getString("device_name");
			String eventType = event.getString("event_type");
			String detectFaceId = event.getString("face_id");
			String detectFace = event.getJSONObject("original_face").getString("url");
			String detectPersonId = event.getString("person_id");
			Integer detectCustomerId = event.getInteger("customer_id");
//			String detectGender = "1".equals(event.getString("gender"))?"男":"女";
			String detectGender = event.getString("gender");
			Integer detectAge = event.getInteger("age");
			String captureAt = event.getString("capture_at");
			String createdAt = event.getString("created_at");
			String status = event.getString("status");
			if("no_face".equals(status.toLowerCase())) return null;
			
			Integer customerId = customer.getInteger("id");
			String customerName = customer.getString("name");
			String gender = customer.getString("gender");
			Integer age = customer.getInteger("age");
			String dob = customer.getString("dob");
			String phone = customer.getString("phone");
			String avatar ="";
			if(customer.containsKey("avatar")) {
				if(null!=customer.getJSONObject("avatar"))//顾客没有底片的avatar对象为空
					avatar = customer.getJSONObject("avatar").getString("url");
			}
			String cardId = customer.getString("card_id");
			String originalFace = customer.getJSONObject("original_face").getString("url");
			Integer eventsCount = customer.getInteger("events_count");
			String firstCaptureAt = customer.getString("capture_at");
			String lastCaptureAt = customer.getString("last_capture_at");
			String personId = customer.getString("person_id");
			
//			String storeName = jo.getString("");
//			String storeNo = jo.getString("");
//			String createTime = jo.getString("");
			String contactId = personId;
//			String faceUrlmd5 = jo.getString("");
//			Double confidence = jo.getDouble("");
			String searchResult = detectPersonId.equals(personId)?"true":"false";
			
			//事件属性
			storeEvent.setEventId(eventId);
			storeEvent.setShopId(shopId);
//			storeEvent.setStoreName(storeName);
//			storeEvent.setStoreNo(storeNo);
			storeEvent.setDeviceId(deviceId);
			storeEvent.setDeviceName(deviceName);
			storeEvent.setEventType(eventType);
			storeEvent.setDetectFaceId(detectFaceId);
			storeEvent.setDetectFace(detectFace);
			storeEvent.setDetectPersonId(detectPersonId);
			storeEvent.setDetectCustomerId(detectCustomerId);
			storeEvent.setDetectGender(detectGender);
			storeEvent.setDetectAge(detectAge);
			storeEvent.setCaptureAt(toDatetime(captureAt));
			storeEvent.setCreatedAt(toDatetime(createdAt));
			storeEvent.setStatus(status);
			//顾客属性
			storeEvent.setCustomerId(customerId);
			storeEvent.setCustomerName(customerName);
			storeEvent.setGender(gender);
			storeEvent.setAge(age);
			storeEvent.setDob(dob);
			storeEvent.setPhone(phone);
			storeEvent.setAvatar(avatar);
			storeEvent.setCardId(cardId);
//			storeEvent.setCreateTime(createDatetime);
			storeEvent.setOriginalFace(originalFace);
			storeEvent.setEventsCount(eventsCount);
			storeEvent.setFirstCaptureAt(toDatetime(firstCaptureAt));
			storeEvent.setLastCaptureAt(toDatetime(lastCaptureAt));
//			storeEvent.setFaceUrlmd5(faceUrlmd5);
			//人脸识别结果属性
			storeEvent.setPersonId(personId);
			storeEvent.setContactId(contactId);
//			storeEvent.setConfidence(confidence);
			storeEvent.setSearchResult(searchResult);
			
//			storeEvent.setSnapTime(snapTime);
			int r = storeEventMapper.insert(storeEvent);
			if(r>0)
				return storeEvent;
			else
				return null;
		}catch(Exception e)
		{
			e.printStackTrace();
			log.error("");
			return null;
		}
	}
	public Date toDatetime(String sdate)
	{
		try {
			if(StringUtils.isBlank(sdate))
				return null;
//	    	String sdate = "2017-02-21T17:52:12.000+08:00";
	    	String s1[] = sdate.split("\\.");
	    	String source = s1[0].replaceAll("T", " ");
	    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	    	Date date = sdf.parse(source);
			return date;
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	public String getAgeGroup(int age)
	{
		if(age<=7)
			return "儿童";
		if(age>=8 && age<=13)
			return "少年";
		if(age>=14 && age<=55)
			return "青年";
//		if(age>=26 && age<=35)
//			return "壮年";
//		if(age>=36 && age<=45)
//			return "盛年";
//		if(age>=46 && age<=55)
//			return "达年";
		if(age>=56 && age<=65)
			return "中年";
		if(age>=66)
			return "老年";
		return "";
	}
}
